home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / machserver / 1.098 / dev / devExabyteTape.c < prev    next >
C/C++ Source or Header  |  1991-08-11  |  12KB  |  328 lines

  1. /* 
  2.  * devExabyteTape.c --
  3.  *
  4.  *      Procedures that set up command blocks and process sense
  5.  *    data for Exabyte tape drives.
  6.  * Definitions for sense data format and status information returned
  7.  * from Exabyte tape drives.  Reference, the "EXB-8200 8mm Tape Drive
  8.  * User's Guide" by Perfect Byte, Inc. 7121 Cass St. Omaha, NE 68132
  9.  *
  10.  * Copyright 1989 Regents of the University of California
  11.  * Permission to use, copy, modify, and distribute this
  12.  * software and its documentation for any purpose and without
  13.  * fee is hereby granted, provided that the above copyright
  14.  * notice appear in all copies.  The University of California
  15.  * makes no representations about the suitability of this
  16.  * software for any purpose.  It is provided "as is" without
  17.  * express or implied warranty.
  18.  */
  19.  
  20. #ifndef lint
  21. static char rcsid[] = "$Header: /sprite/src/kernel/dev/RCS/devExabyteTape.c,v 9.4 91/06/06 11:19:45 mendel Exp $ SPRITE (Berkeley)";
  22. #endif not lint
  23.  
  24.  
  25. #include "sprite.h"
  26. #include "stdio.h"
  27. #include "dev.h"
  28. #include "scsi.h"
  29. #include "scsiTape.h"
  30. #include "scsiDevice.h"
  31. #include "stdlib.h"
  32. #include "fs.h"
  33. #include "exabyteTape.h"
  34. #include "string.h"
  35.  
  36. /*
  37.  * The Exabyte drives have 1K blocks.
  38.  */
  39. #define EXABYTE_BLOCK_SIZE    1024
  40.  
  41. /*
  42.  * Sense data returned from the Exabyte tape controller.
  43.  */
  44. #define EXABYTE_SENSE_BYTES    26
  45. typedef struct {
  46.     ScsiClass7Sense    extSense;    /* 8 Bytes */
  47.     unsigned char pad8;            /* Reserved */
  48.     unsigned char pad;            /* Reserved */
  49.     unsigned char pad10;        /* Reserved */
  50.     unsigned char pad11;        /* Reserved */
  51.     /*
  52.      * SCSI 2 support.
  53.      */
  54.     unsigned char senseCode;        /* 0x4 if sense key is NOT_READY */
  55.     unsigned char senseCodeQualifier;    /* 00 - volume not mounted.
  56.                      * 01 - rewinding or loading */
  57.     unsigned char pad14;        /* Reserved */
  58.     unsigned char pad15;        /* Reserved */
  59.     unsigned char highErrorCnt;        /* High byte of error count */
  60.     unsigned char midErrorCnt;        /* Middle byte of error count */
  61.     unsigned char lowErrorCnt;        /* Low byte of error count */
  62.     /*
  63.      * Error bits that are command dependent.  0 is ok, 1 means error.
  64.      * These are defined on pages 37-38 of the User Manual, Rev.03
  65.      */
  66. #if BYTE_ORDER == BIG_ENDIAN
  67.     unsigned char PF        :1;    /* Power failure */
  68.     unsigned char BPE        :1;    /* SCSI Bus Parity Error */
  69.     unsigned char FPE        :1;    /* Formatted buffer parity error */
  70.     unsigned char ME        :1;    /* Media error */
  71.     unsigned char ECO        :1;    /* Error counter overflow */
  72.     unsigned char TME        :1;    /* Tape motion error */
  73.     unsigned char TNP        :1;    /* Tape not present */
  74.     unsigned char BOT        :1;    /* Set when tape is at BOT */
  75.  
  76.     unsigned char XFR        :1;    /* Transfer Abort Error */
  77.     unsigned char TMD        :1;    /* Tape Mark Detect Error */
  78.     unsigned char WP        :1;    /* Write Protect */
  79.     unsigned char FMKE        :1;    /* File Mark Error */
  80.     unsigned char URE        :1;    /* Data flow underrun. Media error. */
  81.     unsigned char WE1        :1;    /* Max write retries attempted */
  82.     unsigned char SSE        :1;    /* Servo System error.  Catastrophic */
  83.     unsigned char FE        :1;    /* Formatter error.  Catastrophic */
  84.  
  85.     unsigned char pad21        :6;    /* Reserved */
  86.     unsigned char WSEB        :1;    /* Write Splice Error, hit blank tape */
  87.     unsigned char WSEO        :1;    /* Write Splice Error, overshoot */
  88. #else /* BYTE_ORDER == LITTLE_ENDIAN */
  89.  
  90.     unsigned char BOT        :1;    /* Set when tape is at BOT */
  91.     unsigned char TNP        :1;    /* Tape not present */
  92.     unsigned char TME        :1;    /* Tape motion error */
  93.     unsigned char ECO        :1;    /* Error counter overflow */
  94.     unsigned char ME        :1;    /* Media error */
  95.     unsigned char FPE        :1;    /* Formatted buffer parity error */
  96.     unsigned char BPE        :1;    /* SCSI Bus Parity Error */
  97.     unsigned char PF        :1;    /* Power failure */
  98.  
  99.     unsigned char FE        :1;    /* Formatter error.  Catastrophic */
  100.     unsigned char SSE        :1;    /* Servo System error.  Catastrophic */
  101.     unsigned char WE1        :1;    /* Max write retries attempted */
  102.     unsigned char URE        :1;    /* Data flow underrun. Media error. */
  103.     unsigned char FMKE        :1;    /* File Mark Error */
  104.     unsigned char WP        :1;    /* Write Protect */
  105.     unsigned char TMD        :1;    /* Tape Mark Detect Error */
  106.     unsigned char XFR        :1;    /* Transfer Abort Error */
  107.  
  108.     unsigned char WSEO        :1;    /* Write Splice Error, overshoot */
  109.     unsigned char WSEB        :1;    /* Write Splice Error, hit blank tape */
  110.     unsigned char pad21        :6;    /* Reserved */
  111.  
  112. #endif /* BYTE_ORDER */
  113.  
  114.     unsigned char pad22;        /* Reserved */
  115.     unsigned char highRemainingTape;    /* High byte of remaining tape len */
  116.     unsigned char midRemainingTape;    /* Middle byte of remaining tape len */
  117.     unsigned char lowRemainingTape;    /* Low byte of remaining tape len */
  118.  
  119. } ExabyteSense;                /* Known to be 26 Bytes big (for
  120.                      * Drives made in/after 1988) */
  121.  
  122.  
  123. /*
  124.  * Definitions for the mode select command.  The MODE_SELECT data
  125.  * consists of a 4 byte header, zero or one 8 byte block descriptors,
  126.  * and finally from zero to 4 bytes of Vendor Unique Parameters.
  127.  * For simplicity we'll always send 1 block descriptor and 4 parameter bytes.
  128.  */
  129.  
  130. typedef struct ExabyteModeSelBlock {
  131.     unsigned char density;        /* Density code == 0.  Only one dens. */
  132.     unsigned char highCount;        /* == 0 */
  133.     unsigned char midCount;        /* == 0 */
  134.     unsigned char lowCount;        /* == 0 */
  135.     unsigned char pad1;            /* Reserved */
  136.     unsigned char highLength;        /* Length of the blocks on tape */
  137.     unsigned char midLength;        /*    0 means variable length */
  138.     unsigned char lowLength;        /*    Default is 1024 bytes */
  139. } ExabyteModeSelBlock;        /* 8 Bytes */
  140.  
  141.  
  142. typedef struct ExabyteModeSelParams {
  143.     ScsiTapeModeSelectHdr    header;
  144.     ExabyteModeSelBlock    block;
  145. #if BYTE_ORDER == BIG_ENDIAN
  146.     unsigned char cartidgeType    :1;    /* 1 == p5 European.
  147.                      * 0 == P6 Domestic */
  148.     unsigned char        :3;    /* Reserved */
  149.     unsigned char noBusyEnable    :1;    /* 0 == Report Busy Status (default)
  150.                      * 1 == No Busy Enable, cmd queued */
  151.     unsigned char evenByteDscnct :1;    /* 0 == Even or Odd byte disconnect
  152.                      * 1 == Even Byte disconnect */
  153.     unsigned char parityEnable    :1;    /* 0 == Parity disabled (default) */
  154.     unsigned char noAutoLoad    :1;    /* 0 == Auto load enabled (default) */
  155. #else /* BYTE_ORDER == LITTLE_ENDIAN */
  156.  
  157.     unsigned char noAutoLoad    :1;    /* 0 == Auto load enabled (default) */
  158.     unsigned char parityEnable    :1;    /* 0 == Parity disabled (default) */
  159.  
  160.     unsigned char evenByteDscnct :1;    /* 0 == Even or Odd byte disconnect
  161.                      * 1 == Even Byte disconnect */
  162.     unsigned char noBusyEnable    :1;    /* 0 == Report Busy Status (default)
  163.                      * 1 == No Busy Enable, cmd queued */
  164.  
  165.     unsigned char        :3;    /* Reserved */
  166.     unsigned char cartidgeType    :1;    /* 1 == p5 European.
  167.                      * 0 == P6 Domestic */
  168.  
  169. #endif /* BYTE_ORDER */
  170.     unsigned char pad1;            /* RESERVED */
  171.     /*
  172.      * The Motion threashold must exceed the Reconnect threshold.
  173.      * Values represent 1K byte increments.
  174.      * Motion - default 0xF0, valid range 0x01 -> 0xF7
  175.      * Reconnect - default 0x40, valid range 0x01 to 0xF7
  176.      * WRITE - lower motion threshold for faster transfer.
  177.      * READ - raise reconnect threshold for faster transfer.
  178.      *    Basically these control the amount of data kept in the buffer
  179.      *    and hence the latency.
  180.      */
  181.     unsigned char motion;        /* Defines how many Kbytes are buffered
  182.                      * before writing to the tape begins,
  183.                      * or when reconnecting on a read */
  184.     unsigned char reconnect;        /* Defines how many Kbytes are left
  185.                      * in the buffer when the drive
  186.                      * begins filling it again, either
  187.                      * by reading the tape or reconnecting
  188.                      * and getting more data from the 
  189.                      * SCSI bus. */
  190. } ModeSelParams;
  191.  
  192. static ReturnStatus ExabyteError _ARGS_((ScsiTape *tapePtr, 
  193.     unsigned int statusByte, int senseLength, char *senseDataPtr));
  194.  
  195.  
  196. /*
  197.  *----------------------------------------------------------------------
  198.  *
  199.  * DevExabyteAttach --
  200.  *
  201.  *    Initialize the DevSCSITape state for a Exabyte drive.
  202.  *
  203.  * Results:
  204.  *    None.
  205.  *
  206.  * Side effects:
  207.  *    Sets the type and call-back procedures.
  208.  *
  209.  *----------------------------------------------------------------------
  210.  */
  211. /*ARGSUSED*/
  212. ReturnStatus
  213. DevExabyteAttach(devicePtr, devPtr, tapePtr)
  214.     Fs_Device    *devicePtr;    /* Fs_Device being attached. */
  215.     ScsiDevice    *devPtr;    /* SCSI device handle for drive. */
  216.     ScsiTape    *tapePtr;    /* Tape drive state to be filled in. */
  217. {
  218.     ScsiInquiryData    *inquiryPtr;
  219.     /*
  220.      * First we must verify that the attached device is a Exabyte. We do
  221.      * that by examinging the Inquiry data in the ScsiDevice handle. The
  222.      * lack of Inquiry data would imply its not a Exabyte. 
  223.      */
  224.     inquiryPtr = (ScsiInquiryData *) (devPtr->inquiryDataPtr);
  225.     if ( (devPtr->inquiryLength < sizeof(ScsiInquiryData)) ||
  226.      (strncmp((char *) (inquiryPtr->vendorID), "EXABYTE ",8) != 0) ) {
  227.      return DEV_NO_DEVICE;
  228.     }
  229.     /*
  230.      * The exabyte has a different BLOCK and we liked to check the
  231.      * vendor unique bits on error.
  232.      */
  233.     tapePtr->blockSize = EXABYTE_BLOCK_SIZE;
  234.     tapePtr->errorProc = ExabyteError;
  235.     if (!(strncmp((char *)(inquiryPtr->productID), "EXB-8200",8))) {
  236.     tapePtr->name = "Exabyte 8200";
  237.     } else if (!(strncmp((char *)(inquiryPtr->productID), "EXB-8500",8))) {
  238.     tapePtr->name = "Exabyte 8500";
  239.     } else {
  240.     tapePtr->name = "Exabyte UNKNOWN";
  241.     }
  242.     return SUCCESS;
  243. }
  244.  
  245. /*
  246.  *----------------------------------------------------------------------
  247.  *
  248.  * ExabyteError --
  249.  *
  250.  *    Handle error conditions from a Exabyte based tape drive.
  251.  *
  252.  * Results:
  253.  *    An error code.
  254.  *
  255.  * Side effects:
  256.  *    None.
  257.  *
  258.  *----------------------------------------------------------------------
  259.  */
  260. static ReturnStatus
  261. ExabyteError(tapePtr, statusByte, senseLength, senseDataPtr)
  262.     ScsiTape     *tapePtr;    /* SCSI Tape that's complaining. */
  263.     unsigned int statusByte;    /* The status byte of the command. */
  264.     int         senseLength;    /* Length of SCSI sense data in bytes. */
  265.     char     *senseDataPtr;    /* Sense data. */
  266. {
  267.     ReturnStatus status;
  268.     register volatile ExabyteSense *exabyteSensePtr =
  269.         (volatile ExabyteSense *)senseDataPtr;
  270.  
  271.     status = DevSCSITapeError(tapePtr, statusByte, senseLength, senseDataPtr);
  272.     if (status == SUCCESS) {
  273.     return status;
  274.     }
  275.     if (exabyteSensePtr->extSense.badBlockLen) {
  276.     printf("Exabyte Block Length Mismatch\n");
  277.     status = DEV_HARD_ERROR;
  278.     }
  279.     if (exabyteSensePtr->TMD) {
  280.         printf("Warning: Exabyte Tape Mark Detect error\n");
  281.         status = DEV_HARD_ERROR;
  282.     } 
  283.     if (exabyteSensePtr->XFR) {
  284.         printf("Warning: Exabyte Transfer abort error\n");
  285.         status = DEV_HARD_ERROR;
  286.     }
  287.     if (exabyteSensePtr->PF) {
  288.     /* Media changed or after power up */
  289.     }
  290.     if (exabyteSensePtr->BPE) {
  291.     printf("Warning: Exabyte SCSI Bus Parity error\n");
  292.     }
  293.     if (exabyteSensePtr->FPE) {
  294.     printf("Warning: Exabyte Formatter Parity error\n");
  295.     }
  296.     if (exabyteSensePtr->ME) {
  297.     /* Media Error already reported via sense key */
  298.     }
  299.     if (exabyteSensePtr->ECO) {
  300.     printf("Warning: Exabyte error counter overflow\n");
  301.     }
  302.     if (exabyteSensePtr->TME) {
  303.     printf("Warning: Exabyte Tape Motion error\n");
  304.     }
  305.     if (exabyteSensePtr->TNP) {
  306.     printf("Warning: Exabyte tape not present\n");
  307.     }
  308.     if (exabyteSensePtr->BOT) {
  309.     /* At the beginning of tape */
  310.     }
  311.     if (exabyteSensePtr->FMKE) {
  312.     printf("Exabyte File Mark Error\n");
  313.     }
  314.     if (exabyteSensePtr->URE) {
  315.     printf("Warning: Exabyte Data Flow Underrun\n");
  316.     }
  317.     if (exabyteSensePtr->WE1) {
  318.     printf("Warning: Exabyte maximum write retries attempted\n");
  319.     }
  320.     if (exabyteSensePtr->SSE) {
  321.     printf("Warning: Exabyte Servo System error, catastrophic failure!\n");
  322.     }
  323.     if (exabyteSensePtr->FE) {
  324.     printf("Warning: Exabyte Formatter error, catastrophic failure!\n");
  325.     }
  326.     return(status);
  327. }
  328.